import type { Plugin } from 'vite'
import { parse } from '@babel/parser'
import traverse from '@babel/traverse'
import MagicString from 'magic-string'
import type { NodePath } from '@babel/traverse'
import type { CallExpression } from '@babel/types'

// 插件选项类型
export interface RemoveConsoleOptions {
  preserve?: string[] // 保留哪些 console 方法
}

export default function removeConsolePlugin(options: RemoveConsoleOptions = {}): Plugin {
  const preserve = options.preserve || []

  return {
    name: 'vite-plugin-remove-console-advanced',
    apply: 'build',
    enforce: 'post',

    transform(code, id) {
      if (!/\.(js|ts|vue|jsx|tsx)$/.test(id)) return

      const ast = parse(code, {
        sourceType: 'module',
        plugins: ['typescript', 'jsx']
      })

      const s = new MagicString(code)

      traverse(ast, {
        ExpressionStatement(path) {
          const expr = path.node.expression

          // 删除独立的 console.xxx()
          if (
            expr.type === 'CallExpression' &&
            expr.callee.type === 'MemberExpression' &&
            expr.callee.object.type === 'Identifier' &&
            expr.callee.object.name === 'console'
          ) {
            const method = expr.callee.property
            const methodName = method.type === 'Identifier' ? method.name : ''

            if (!preserve.includes(methodName)) {
              s.remove(path.node.start!, path.node.end!)
            }
          }
        },

        DebuggerStatement(path) {
          // 删除 debugger
          s.remove(path.node.start!, path.node.end!)
        }
      })

      if (s.hasChanged()) {
        return {
          code: s.toString(),
          map: s.generateMap({ hires: true })
        }
      }
    }
  }
}
